package Generics;

import java.util.ArrayList;
import java.util.Iterator;

/**
 * ClassName:GenericsDome001
 * Package:Gather.DataStructure
 * Description:
 *
 * @Author:ZhangXin
 * @Create2023/2/7-18:15
 * @Version:v1.0
 */
public class GenericsDome001 {
    //泛型概述
    //统一数据类型
    //把运行时期的问题提前到了编译期间,避免了强制类型转换可能出现的异常,因为在编译阶段类型就能确定下来

    /*泛型：是JDK5中引入的特性,可以在编译阶段约束操作的数据类型,并进行检查
    * 泛型的格式：<数据类型>
    * 注意：泛型只能支持引用数据类型
    * */
    public static void main(String[] args) {
        //没有泛型的时候,集合如何存储数据
        //结论：如果我们没有给集合指定类型,默认认为所有的数据类型都是Object类型
        //此时可以往集合添加任意的数据类型
        //带来的坏处：我们在获取数据的时候,无法使用他的特有行为

        //此时推出了泛型,可以在添加数据的时候就把类型进行统一
        //而且我们在获取数据的时候,也省的强转了,非常方便

        //创建集合对象
        ArrayList list = new ArrayList();
        //添加数据
        list.add(123);
        list.add("aaa");
        list.add(new Student("zhangsan",23));

        //遍历集合获取里面的每一个元素
        Iterator it = list.iterator();
        while (it.hasNext()){
            Object obj = it.next();
            //多态的弊端是不能访问子类的特有功能
            System.out.println(obj);
        }

    }
}
/*
* 扩展知识点：Java中的泛型是伪泛型
* (泛型的擦除)
*
* 泛型的细节
* 泛型中不能写基本数据类型
* 指定泛型的具体类型后,传递数据时,可以传入该类型或者其子类型
* 如果不写泛型,类型默认是Object*/

/*
* 泛型可以在很多地方进行定义
*
* 类后面->(泛型类)
*   使用场景：当一个类中,某各变量的数据类型不确定时,就可以定义带有泛型的类
*   格式：修饰符 class 类名<类型>{}
*   举例：public class ArrayList<E>{}
*   此处的E可以理解为变量,但是不是用来记录数据的,而是记录数据类型的,可以写成：T、E、K、V
*
* 方法上面->(泛型方法)
*   方法中形参类型不确定时,可以使用类名后面定义的泛型<E>
*   方法中形参类型不确定时
*       1.使用类名后面定义的泛型(所有方法都能用)
*       2.在方法申明上定义自己的泛型(只有本方法可以使用)
*   格式：修饰符<类型>返回值类型 方法名(类型 变量名){}
*   举例：public<T>void show(T t){}
*
*
* 接口后面->(泛型接口)
*   格式：修饰符interface 接口名<类型>{}
*   举例：public interface List<E>{}
*   泛型接口的实现：
*       1.实现类给出具体类型
*       2.实现类延续泛型,创建对象时再确定*/